home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / advanced97 / FIRE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  12.0 KB  |  481 lines

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6. #include "sm.h"
  7.  
  8. /* Some <math.h> files do not define M_PI... */
  9. #ifndef M_PI
  10. #define M_PI 3.14159265358979323846
  11. #endif
  12.  
  13. #ifndef __sgi
  14. /* Most math.h's do not define float versions of the trig functions. */
  15. #define sinf(x) ((float)sin((x)))
  16. #define cosf(x) ((float)cos((x)))
  17. #define atan2f(y, x) ((float)atan2((y), (x)))
  18. #endif
  19.  
  20. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  21. #define glBindTexture    glBindTextureEXT
  22. #endif
  23.  
  24. static void *smoke;
  25. static int marshmallow;
  26. static int the_texture;
  27. static int texture_count;
  28. static int texture = 1;
  29. static float rot = 0;
  30. static float opacity = 1.0;
  31. static float intensity = 1.0;
  32. static float transx, transy, rotx, roty;
  33. static int ox = -1, oy = -1;
  34. static int mot = 0;
  35. #define PAN    1
  36. #define ROT    2
  37.  
  38. void
  39. pan(int x, int y) {
  40.     transx +=  (x-ox)/500.;
  41.     transy -= (y-oy)/500.;
  42.     ox = x; oy = y;
  43.     glutPostRedisplay();
  44. }
  45.  
  46. void
  47. rotate(int x, int y) {
  48.     rotx += x-ox;
  49.     if (rotx > 360.) rotx -= 360.;
  50.     else if (rotx < -360.) rotx += 360.;
  51.     roty += y-oy;
  52.     if (roty > 360.) roty -= 360.;
  53.     else if (roty < -360.) roty += 360.;
  54.     ox = x; oy = y;
  55.     glutPostRedisplay();
  56. }
  57.  
  58. void
  59. motion(int x, int y) {
  60.     if (mot == PAN) pan(x, y);
  61.     else if (mot == ROT) rotate(x,y);
  62. }
  63.  
  64. void
  65. mouse(int button, int state, int x, int y) {
  66.     if(state == GLUT_DOWN) {
  67.     switch(button) {
  68.     case GLUT_LEFT_BUTTON:
  69.         mot = PAN;
  70.         motion(ox = x, oy = y);
  71.         break;
  72.     case GLUT_RIGHT_BUTTON:
  73.         mot = ROT;
  74.         motion(ox = x, oy = y);
  75.         break;
  76.     case GLUT_MIDDLE_BUTTON:
  77.         break;
  78.     }
  79.     } else if (state == GLUT_UP) {
  80.     mot = 0;
  81.     }
  82. }
  83.  
  84. void afunc(void) {
  85.     static int state;
  86.     if (state ^= 1)
  87.     glEnable(GL_ALPHA_TEST);
  88.     else
  89.     glDisable(GL_ALPHA_TEST);
  90. }
  91.  
  92. void bfunc(void) {
  93.     static int state;
  94.     if (state ^= 1)
  95.     glEnable(GL_BLEND);
  96.     else
  97.     glDisable(GL_BLEND);
  98. }
  99.  
  100. void mfunc(void) {
  101.     marshmallow += 1;
  102.     if (marshmallow > 2) marshmallow = 0;
  103. }
  104.  
  105. void sfunc(void) {
  106.     the_texture++;
  107.     if (the_texture >= texture_count) the_texture = 0;
  108. }
  109.  
  110. void tfunc(void) {
  111.     static int state;
  112.     if (state ^= 1)
  113.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  114.     else
  115.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  116. }
  117.  
  118. void fourfunc(void) {
  119.     static int state;
  120.     GLenum wrap;
  121.     int i;
  122.  
  123.     glMatrixMode(GL_TEXTURE);
  124.     if (state ^= 1) {
  125.     wrap = GL_REPEAT;
  126.     glScalef(4.f, 4.f, 1.f);
  127.     } else {
  128.     wrap = GL_CLAMP;
  129.     glLoadIdentity();
  130.     }
  131.     glMatrixMode(GL_MODELVIEW);
  132.  
  133.     for(i = 0; i < texture_count; i++) {
  134.     glBindTexture(GL_TEXTURE_2D, i+1);
  135.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
  136.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
  137.     }
  138. }
  139.  
  140. void help(void) {
  141.     printf("Usage: fire image0 ... imagen\n");
  142.     printf("'h'            - help\n");
  143.     printf("'a'            - toggle alpha test\n");
  144.     printf("'b'            - toggle blend\n");
  145.     printf("'s'            - single step\n");
  146.     printf("'t'            - toggle MODULATE or REPLACE\n");
  147.     printf("'m'            - marshmallow\n");
  148.     printf("'x'            - toggle animation\n");
  149.     printf("left mouse     - pan\n");
  150.     printf("right mouse    - rotate\n");
  151. }
  152.  
  153. void init(int argc, char *argv[]) {
  154.     unsigned *image;
  155.     int i, width, height, components;
  156.     GLfloat pos[] = { 0.f, 1.f, 1.f, 0.f};
  157.  
  158.     glEnable(GL_TEXTURE_2D);
  159.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  160.  
  161.     for(i = 0; i < argc; i++) {
  162.     image = read_texture(argv[i], &width, &height, &components);
  163.     if (image == NULL) {
  164.         fprintf(stderr, "Error: Can't load image file \"%s\".\n",
  165.             argv[i]);
  166.         exit(EXIT_FAILURE);
  167.     } else {
  168.         printf("%d x %d image loaded\n", width, height);
  169.     }
  170.     glBindTexture(GL_TEXTURE_2D, i+1);
  171.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  172.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  173.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  174.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  175.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  176.                  height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
  177.     texture_count++;
  178.     }
  179.  
  180.     glBindTexture(GL_TEXTURE_2D, 1+texture_count);
  181.     image = read_texture("data/smoke.la", &width, &height, &components);
  182.     if (image == NULL) {
  183.     fprintf(stderr, "Error: Can't load image file \"%s\".\n", "smoke.la");
  184.     exit(EXIT_FAILURE);
  185.     }
  186.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  187.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  188.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  189.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  190.     glTexImage2D(GL_TEXTURE_2D, 0, components, width,
  191.          height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
  192.     smoke = new_smoke(0.f, 0.f, 0.f, .0f, 2.5f, 0.f, 25, .4f, 1+texture_count);
  193.  
  194.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  195.     glEnable(GL_TEXTURE_2D);
  196.     glClearColor(.25f, .25f, .25f, .25f);
  197.  
  198.     glLightfv(GL_LIGHT0, GL_POSITION, pos);
  199.     glMatrixMode(GL_PROJECTION);
  200.     glLoadIdentity();
  201.     gluPerspective(50.,1.,.1,20.);
  202.     glMatrixMode(GL_MODELVIEW);
  203.     glLoadIdentity();
  204.     glTranslatef(0.,0.,-5.5);
  205.     glClearColor(.25f, .25f, .75f, .25f);
  206.  
  207.     glAlphaFunc(GL_GREATER, 0.016);
  208.     glEnable(GL_ALPHA_TEST);
  209.  
  210.     glEnable(GL_BLEND);
  211.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  212.     glEnable(GL_DEPTH_TEST);
  213.     glEnable(GL_LIGHT0);
  214.     glEnable(GL_NORMALIZE);
  215. }
  216.  
  217. void
  218. animate(void) {
  219.     static int cnt;
  220.     if (cnt++ == 2) {
  221.     the_texture++;
  222.     if (the_texture >= texture_count) the_texture = 0;
  223.     cnt = 0;
  224.     }
  225.     update_smoke(smoke, .003);
  226.     glutPostRedisplay();
  227. }
  228.  
  229. void
  230. xfunc(void) {
  231.     static int state = 1;
  232.     glutIdleFunc((state ^= 1) ? animate : NULL);
  233. }
  234.  
  235. void
  236. cube(void) {
  237.     glBegin(GL_QUADS);
  238.     glNormal3f(0.f, 0.f, -1.f);
  239.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  240.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  241.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0, -1.0);
  242.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0, -1.0);
  243.  
  244.     glNormal3f(0.f, 0.f, 1.f);
  245.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0,  1.0);
  246.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0,  1.0);
  247.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  248.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  249.  
  250.     glNormal3f(0.f, 1.f, 0.f);
  251.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,  1.0, -1.0);
  252.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, -1.0);
  253.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  254.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  255.  
  256.     glNormal3f(0.f, -1.f, 0.f);
  257.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  258.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  259.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0,  1.0);
  260.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0,  1.0);
  261.  
  262.     glNormal3f( 1.f, 0.f, 0.f);
  263.     glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
  264.     glTexCoord2f(1.0, 0.0); glVertex3f( 1.0,  1.0, -1.0);
  265.     glTexCoord2f(1.0, 1.0); glVertex3f( 1.0,  1.0,  1.0);
  266.     glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0,  1.0);
  267.  
  268.     glNormal3f(-1.f, 0.f, 0.f);
  269.     glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
  270.     glTexCoord2f(1.0, 0.0); glVertex3f(-1.0,  1.0, -1.0);
  271.     glTexCoord2f(1.0, 1.0); glVertex3f(-1.0,  1.0,  1.0);
  272.     glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0,  1.0);
  273.     glEnd();
  274. }
  275.  
  276. void
  277. logs(void) {
  278.     static GLUquadricObj *quadric;
  279.  
  280.     if (!quadric) {
  281.     quadric = gluNewQuadric();
  282.     glNewList(100, GL_COMPILE);
  283.     gluQuadricOrientation(quadric, GLU_OUTSIDE);
  284.     glTranslatef(0.f, 0.f, -2.f);
  285.     gluCylinder(quadric, .5, .5, 4., 5, 1);
  286.     glTranslatef(0.f, 0.f, 4.f);
  287.     gluDisk(quadric, 0., .5, 10, 1);
  288.     glTranslatef(0.f, 0.f, -4.f);
  289.     gluQuadricOrientation(quadric, GLU_INSIDE);
  290.     gluDisk(quadric, 0., .5, 10, 1);
  291.     glEndList();
  292.     }
  293.     glPushMatrix();
  294.     glTranslatef(0.f, -.5f, 0.f);
  295.     glColor3f(.55f, .14f, .14f);
  296.     glPushMatrix();
  297.     glRotatef(55., 0., 1., 0.);
  298.     glCallList(100);
  299.     glPopMatrix();
  300.     glPushMatrix();
  301.     glRotatef(-55., 0., 1., 0.);
  302.     glCallList(100);
  303.     glPopMatrix();
  304.     if (marshmallow) {
  305.     glPushMatrix();
  306.     glColor4f(1.f, 1.f, 1.f, 1.f);
  307.     glTranslatef(0.f, 1.7f, 0.f);
  308.     glRotatef(45.f, 0.f, 0.f, 1.f);
  309.     glRotatef(90.f, 0.f, 1.f, 0.f);
  310.     glScalef(1., 1., .25f);
  311.     glCallList(100);
  312.     glPopMatrix();
  313.  
  314.     glPushMatrix();
  315.     glColor4f(.1f, .1f, .1f, 1.f);
  316.     glTranslatef(1.5f, 3.4f, 0.f);
  317.     glRotatef(45.f, 0.f, 0.f, 1.f);
  318.     glRotatef(90.f, 0.f, 1.f, 0.f);
  319.     glScalef(.2f, .2f, 1.f);
  320.     glCallList(100);
  321.     glPopMatrix();
  322.  
  323.     if (marshmallow == 2) {
  324.         extern void drawDinosaur(void);
  325.         glDisable(GL_COLOR_MATERIAL);
  326.         glPushMatrix();
  327.         glTranslatef(10.f, 0.f, 0.f);
  328.         glRotatef(180.f, 0.f, 1.f, 0.f);
  329.         glScalef(.5f, .5f, .5f);
  330.         drawDinosaur();
  331.         glPopMatrix();
  332.     }
  333.     }
  334.     glPopMatrix();
  335. }
  336. static void calcMatrix(void);
  337.  
  338. void display(void) {
  339.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  340.  
  341.     glLoadIdentity();
  342. #define RAD(x) (((x)*M_PI)/180.)
  343.     gluLookAt(-sinf(RAD(rotx))*5.5,transy,cosf(RAD(rotx))*5.5, 0.,0.,0., 0.,1.,0.);
  344.  
  345.     glTranslatef(0.f, 0.f, transx*10.f);
  346.  
  347.     /* floor */
  348.     glColor4f(0.f,.2f,0.f,1.f);
  349.     glBegin(GL_POLYGON);
  350.     glVertex3f(-4.0, -1.0, -4.0);
  351.     glVertex3f( 4.0, -1.0, -4.0);
  352.     glVertex3f( 4.0, -1.0,  4.0);
  353.     glVertex3f(-4.0, -1.0,  4.0);
  354.     glEnd();
  355.  
  356.     glEnable(GL_COLOR_MATERIAL);
  357.     glEnable(GL_LIGHTING);
  358.     glColor3f(.1f,.1f,.1f);
  359.     glPushMatrix();
  360.     glTranslatef(-1.f, -1.+.2f, -1.5f);
  361.     glScalef(.2f,.2f, .2f);
  362.     logs();
  363.     /*cube();*/
  364.     glDisable(GL_LIGHTING);
  365.     glPopMatrix();
  366.  
  367.     glPushMatrix();
  368.     glTranslatef(-1.f, -1.f+.2f, -1.5f);
  369.     calcMatrix();
  370.     draw_smoke(smoke);
  371.     glPopMatrix();
  372.  
  373.     glPushMatrix();
  374.     glTranslatef(/*(delta/2.f*/-1.f, /*delta*/-.25f, -1.5f);
  375.     calcMatrix();
  376.     glScalef(1.f,1.f,1.);
  377.     if (texture) {
  378.     glBindTexture(GL_TEXTURE_2D, the_texture+1);
  379.     glEnable(GL_TEXTURE_2D);
  380.     }
  381.     glColor4f(intensity, intensity, intensity, opacity);
  382.     glRotatef(rot, 0., 0., 1.);
  383.     glDepthMask(0);
  384.     glBegin(GL_POLYGON);
  385.     glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0);
  386.     glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0);
  387.     glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0);
  388.     glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0);
  389.     glEnd();
  390.     glDepthMask(1);
  391.     glPopMatrix();
  392.     glDisable(GL_TEXTURE_2D);
  393.  
  394.     glutSwapBuffers();
  395. }
  396.  
  397. void reshape(int w, int h) {
  398.     glViewport(0, 0, w, h);
  399. }
  400.  
  401. /* ARGSUSED1 */
  402. void
  403. key(unsigned char key, int x, int y) {
  404.     switch(key) {
  405.     case 'a': afunc(); break;
  406.     case 'b': bfunc(); break;
  407.     case 'h': help(); break;
  408.     case 'm': mfunc(); break;
  409.     case 's': sfunc(); break;
  410.     case 't': tfunc(); break;
  411.     case 'x': xfunc(); break;
  412.     case '\033': exit(EXIT_SUCCESS); break;
  413.     default: break;
  414.     }
  415.     glutPostRedisplay();
  416. }
  417.  
  418. int main(int argc, char** argv) {
  419.     glutInitWindowSize(512, 512);
  420.     glutInit(&argc, argv);
  421.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  422.     (void)glutCreateWindow(argv[0]);
  423.     init(argc-1, argv+1);
  424.     glutDisplayFunc(display);
  425.     glutKeyboardFunc(key);
  426.     glutReshapeFunc(reshape);
  427.     glutMouseFunc(mouse);
  428.     glutMotionFunc(motion);
  429.     glutIdleFunc(animate);
  430.     glutMainLoop();
  431.     return 0;
  432. }
  433.  
  434. void
  435. buildRot(float theta, float x, float y, float z, float m[16]) {
  436.     float d = x*x + y*y + z*z;
  437.     float ct = cosf(RAD(theta)), st = sinf(RAD(theta));
  438.  
  439.     /* normalize */
  440.     if (d > 0) {
  441.     d = 1/d;
  442.     x *= d;
  443.     y *= d;
  444.     z *= d;
  445.     }
  446.  
  447.     m[ 0] = 1; m[ 1] = 0; m[ 2] = 0; m[ 3] = 0;
  448.     m[ 4] = 0; m[ 5] = 1; m[ 6] = 0; m[ 7] = 0;
  449.     m[ 8] = 0; m[ 9] = 0; m[10] = 1; m[11] = 0;
  450.     m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
  451.  
  452.     /* R = uu' + cos(theta)*(I-uu') + sin(theta)*S
  453.      *
  454.      * S =  0  -z   y    u' = (x, y, z)
  455.      *        z   0  -x
  456.      *       -y   x   0
  457.      */
  458.  
  459.      m[0] = x*x + ct*(1-x*x) + st*0;
  460.      m[4] = x*y + ct*(0-x*y) + st*-z;
  461.      m[8] = x*z + ct*(0-x*z) + st*y;
  462.  
  463.      m[1] = y*x + ct*(0-y*x) + st*z;
  464.      m[5] = y*y + ct*(1-y*y) + st*0;
  465.      m[9] = y*z + ct*(0-y*z) + st*-x;
  466.  
  467.      m[2] = z*x + ct*(0-z*x) + st*-y;
  468.      m[6] = z*y + ct*(0-z*y) + st*x;
  469.      m[10]= z*z + ct*(1-z*z) + st*0;
  470. }
  471.  
  472. static void
  473. calcMatrix(void) {
  474.     float mat[16];
  475.  
  476.     glGetFloatv(GL_MODELVIEW_MATRIX, mat);
  477.  
  478.     buildRot(-180*atan2f(mat[8], mat[10])/M_PI, 0, 1, 0, mat);
  479.     glMultMatrixf(mat);
  480. }
  481.